﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using TranslatorService.Speech;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.Storage;
using Windows.UI.Popups;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

// The Basic Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234237

namespace TranslatorService.Example
{
    /// <summary>
    /// A basic page that provides characteristics common to most applications.
    /// </summary>
    public sealed partial class MainPage : TranslatorService.Example.Common.LayoutAwarePage
    {
        private const string CLIENT_ID = "";
        private const string CLIENT_SECRET = "";

        private SpeechSynthesizer speech;

        private class LanguageInfo
        {
            public string LanguageCode { get; set; }
            public string DisplayName { get; set; }
        }

        public MainPage()
        {
            this.InitializeComponent();

            speech = new SpeechSynthesizer(CLIENT_ID, CLIENT_SECRET);
            speech.AudioFormat = SpeakStreamFormat.MP3;
            speech.AudioQuality = SpeakStreamQuality.MaxQuality;
            speech.AutoDetectLanguage = true;
            speech.AutomaticTranslation = true;

        }

        /// <summary>
        /// Populates the page with content passed during navigation.  Any saved state is also
        /// provided when recreating a page from a prior session.
        /// </summary>
        /// <param name="navigationParameter">The parameter value passed to
        /// <see cref="Frame.Navigate(Type, Object)"/> when this page was initially requested.
        /// </param>
        /// <param name="pageState">A dictionary of state preserved by this page during an earlier
        /// session.  This will be null the first time a page is visited.</param>
        protected async override void LoadState(Object navigationParameter, Dictionary<String, Object> pageState)
        {
            if (string.IsNullOrWhiteSpace(CLIENT_ID) || string.IsNullOrWhiteSpace(CLIENT_SECRET))
            {
                MessageDialog dialog = new MessageDialog("You must obtain a Client ID and Secret in order to use this application. Please visit Azure DataMarket at https://datamarket.azure.com/developer/applications to get one.\r\nThen, go to https://datamarket.azure.com/dataset/1899a118-d202-492c-aa16-ba21c33c06cb and subscribe the Microsoft Translator Service.\n", "Translator Service Example");
                await dialog.ShowAsync();
                return;
            }

            WaitProgressBar.Visibility = Visibility.Visible;

            // Gets the list of all supported languages.
            var languageItems = new List<LanguageInfo>();
            var languages = await speech.GetLanguagesAsync();
            foreach (var language in languages)
            {
                var culture = new CultureInfo(language);
                languageItems.Add(new LanguageInfo { LanguageCode = language, DisplayName = culture.DisplayName });
            }

            LanguagesComboBox.ItemsSource = languageItems.OrderBy(i => i.DisplayName);
            LanguagesComboBox.SelectedItem = languageItems.Where(language => language.DisplayName == CultureInfo.CurrentUICulture.DisplayName).FirstOrDefault();

            WaitProgressBar.Visibility = Visibility.Collapsed;
        }

        /// <summary>
        /// Preserves state associated with this page in case the application is suspended or the
        /// page is discarded from the navigation cache.  Values must conform to the serialization
        /// requirements of <see cref="SuspensionManager.SessionState"/>.
        /// </summary>
        /// <param name="pageState">An empty dictionary to be populated with serializable state.</param>
        protected override void SaveState(Dictionary<String, Object> pageState)
        {
        }

        private void AutoDetectLanguageCheckBox_Click(object sender, RoutedEventArgs e)
        {
            LanguagesComboBox.IsEnabled = !AutoDetectLanguageCheckBox.IsChecked.GetValueOrDefault();
        }

        private async void SpeakButton_Click(object sender, RoutedEventArgs e)
        {
            if (string.IsNullOrWhiteSpace(SpeechText.Text))
                return;

            WaitProgressBar.Visibility = Visibility.Visible;

            // Checks if we want to use auto-detection and automatic translation.
            speech.AutoDetectLanguage = AutoDetectLanguageCheckBox.IsChecked.Value;
            speech.AutomaticTranslation = AutomaticTranslationCheckBox.IsChecked.Value;

            // If auto language detection is enabled, don't use the selected language, because it will be auto-detected.
            string language = speech.AutoDetectLanguage ? null : ((LanguageInfo)LanguagesComboBox.SelectedItem).LanguageCode;

            // Gets the audio stream.
            var stream = await speech.GetSpeakStreamAsync(SpeechText.Text, language);

            // Reproduces the audio stream using a MediaElement.
            SpeechMediaElement.SetSource(stream, speech.MimeContentType);

            WaitProgressBar.Visibility = Visibility.Collapsed;
        }

        private async void TranslateButton_Click(object sender, RoutedEventArgs e)
        {
            if (string.IsNullOrWhiteSpace(SpeechText.Text))
                return;

            WaitProgressBar.Visibility = Visibility.Visible;

            // Translates the text in the specified language.
            string translatedText = await speech.TranslateAsync(SpeechText.Text, ((LanguageInfo)LanguagesComboBox.SelectedItem).LanguageCode);
            TranslatedText.Text = translatedText;

            WaitProgressBar.Visibility = Visibility.Collapsed;
        }

        private async void DetectLanguageButton_Click(object sender, RoutedEventArgs e)
        {
            if (string.IsNullOrWhiteSpace(SpeechText.Text))
                return;

            WaitProgressBar.Visibility = Visibility.Visible;

            // Detects the language of the text.
            string detectedLanguage = await speech.DetectLanguageAsync(SpeechText.Text);

            WaitProgressBar.Visibility = Visibility.Collapsed;

            CultureInfo culture = new CultureInfo(detectedLanguage);
            string message = string.Format("The detected language is {0}.", culture.DisplayName);
            MessageDialog dialog = new MessageDialog(message, "Translator Service Example");
            await dialog.ShowAsync();
        }

        private async void MailButton_Click(object sender, RoutedEventArgs e)
        {
            await Windows.System.Launcher.LaunchUriAsync(new Uri("mailto:marco.minerva@gmail.com"));
        }
    }
}
